package com.yuncheng.spcyApi.flow;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.spcyApi.busService.FlowJobBlsxService;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.spcyApi.constant.flow.FlowNodeConstant;
import com.yuncheng.spcyApi.entity.*;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.spcyApi.service.*;
import com.yuncheng.spcyApi.utils.GetCurrentUserUtils;
import com.yuncheng.spcyApi.utils.GetUuIdUtils;
import com.yuncheng.spcyApi.utils.StringPatternUtils;
import com.yuncheng.vo.CurrentUserVo;
import com.yuncheng.spcyApi.vo.common.Result;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Component(value = "FlowNodeService")
public class FlowNodeService {
    private static final Logger log = LoggerFactory.getLogger(FlowNodeService.class);

    @Resource
    @Lazy
    private ISysFlowNodeService sysFlowNodeService;

    @Resource
    @Lazy
    private ISpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private FlowNodeDbrService flowNodeDbrService;

    @Resource
    @Lazy
    private ISysFlowPageService sysFlowPageService;

    @Resource
    @Lazy
    private FlowJobBlsxService flowJobBlsxService;

    @Resource
    @Lazy
    private ISysJobService sysJobService;

    @Resource
    @Lazy
    private SpcyFlowService spcyFlowService;

    @Resource
    @Lazy
    private JcyYbkpFlowService jcyYbkpFlowService;

    @Resource
    @Lazy
    private JcyRckpFlowService jcyRckpFlowService;

    @Resource
    @Lazy
    private JcyRckpHpFlowService jcyRckpHpFlowService;

    @Resource
    @Lazy
    private JcyNdkpFlowService jcyNdkpFlowService;

    @Resource
    @Lazy
    private TxwjFlowService txwjFlowService;

    @Resource
    @Lazy
    private ThzwYpscFlowService thzwYpscFlowService;

    @Resource
    @Lazy
    private BqbzFlowService bqbzFlowService;

    @Resource
    @Lazy
    private SpcySjxdFlowService spcySjxdFlowService;

    /*@Resource
    @Lazy
    private JcyTssxbxsqFlowService jcyTssxbxsqFlowService;*/

    /**
     * 初始化流程-指定流程编码
     * @param lcmbCode
     * @param pid
     * @param currentUser
     * @return
     */
    public Result createProcess(String lcmbCode, String pid, CurrentUserVo currentUser){
        //获取流程模板的第一个环节
        SysFlowTemple sysFlowTemple = sysFlowNodeService.getCode(lcmbCode);

        List<SysFlowNode> node = sysFlowNodeService.getFirstNode(sysFlowTemple.getId());

        List<SpcySqsxJob> list = spcySqsxJobService.list(new LambdaQueryWrapper<SpcySqsxJob>()
                .eq(SpcySqsxJob::getFpid, pid)
                .eq(SpcySqsxJob::getFnodeid, node.get(0).getId())
                .ne(SpcySqsxJob::getFblzt, SpcyConstant.BLZT_YB)
        );

        if(list.size() > 0){
            throw new BusinessException("流程已经初始化完成，请勿再次申请！");
        }

        return createJob(lcmbCode,pid,"",node.get(0),null,null,currentUser);
    }

    /**
     * 创建流程
     * @param lcmbCode 流程编码code
     * @param pid 业务id
     * @param dbrId 待办人id
     * @param nowNode 当前节点对象
     * @param nowJob 当前流程对象
     * @param nextNodeId 下一环节id
     * @param currentUser 当前登陆人
     * @return
     */
    public Result createJob(String lcmbCode, String pid, String dbrId, SysFlowNode nowNode, SpcySqsxJob nowJob, String nextNodeId, CurrentUserVo currentUser){
        return this.createJob(lcmbCode, pid, dbrId, nowNode, nowJob, nextNodeId, currentUser, null);
    }

    /**
     * 创建流程
     * @param lcmbCode 流程编码code
     * @param pid 业务id
     * @param dbrId 待办人id
     * @param nowNode 当前节点对象
     * @param nowJob 当前流程对象
     * @param nextNodeId 下一环节id
     * @param currentUser 当前登陆人
     * @param lcbt 流程标题
     * @param lczy 流程摘要
     * @param lclx 流程业务类型
     * @return
     */
    public Result createJob(String lcmbCode, String pid, String dbrId, SysFlowNode nowNode, SpcySqsxJob nowJob, String nextNodeId, CurrentUserVo currentUser, String lcbt, String lczy, String lclx){
        return this.createJob(lcmbCode, pid, dbrId, nowNode, nowJob, nextNodeId, currentUser, null, lcbt, lczy, lclx);
    }

    /**
     * 创建流程
     * @param lcmbCode 流程编码code
     * @param pid 业务id
     * @param dbrId 待办人id
     * @param nowNode 当前节点对象
     * @param nowJob 当前流程对象
     * @param nextNodeId 下一环节id
     * @param currentUser 当前登陆人
     * @param dbrMap 待办人对象（dbrId,dbr）
     * @param lcbt 流程标题
     * @param lczy 流程摘要
     * @param lclx 流程业务类型
     * @return
     * {
     *     result.SpcySqsxJob
     * }
     */
    public Result createJob(String lcmbCode, String pid, String dbrId, SysFlowNode nowNode, SpcySqsxJob nowJob, String nextNodeId, CurrentUserVo currentUser, Map dbrMap, String lcbt, String lczy, String lclx){

        String dbr = "";
        if (dbrMap == null){
            dbrMap = this.verifryNextDbr(lcmbCode, pid, dbrId, nowNode, nowJob, nextNodeId, currentUser);
        }
        dbrId = dbrMap.get("dbrId").toString();
        dbr = dbrMap.get("dbr").toString();
        nowNode = (SysFlowNode) dbrMap.get("nowNode");

        String fnodeid = nowNode.getId();
        String fblfs = nowNode.getFblfs();
        String fjdmc = nowNode.getFjdmc();
        String lcmc = sysFlowNodeService.getCode(lcmbCode).getFlcmc();

        SpcySqsxJob job = new SpcySqsxJob();
        job.setId(GetUuIdUtils.ReplaceUuId());
        job.setFpid(pid);
        job.setFblfs(fblfs);
        job.setFhjmc(fjdmc);

        if(nowJob == null){
            job.setFsyhjid("");
        }else {
            job.setFsyhjid(nowJob.getId());
        }

        job.setFlcmc(lcmc); // 流程名称
        job.setFnodeid(fnodeid); // 结点id

        // 发送人
        if(currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }

        job.setFfssj(new Date());

        job.setFdbr(dbr);
        job.setFdbrid(dbrId);

        job.setFydbr(dbr);
        job.setFydbrid(dbrId);

        job.setFblzt(SpcyConstant.BLZT_DB);
        job.setFbllx(SpcyConstant.BLLX_DB);

        // 是否为审评查验流程
        boolean isSpcyFlow = SpcyFlowConstant.verifyIsSpcyFlow(lcmbCode);

        // 是否为审评查验流程 计算办理天数，是否超时状态
        if (isSpcyFlow){
            job.setFksyts(flowJobBlsxService.getSqsxSysx(pid));
            job.setFjzblsj(flowJobBlsxService.jsNodeJzrq(job.getFfssj(),job.getFksyts()));
        }

        job.setFbz(lczy);
        spcySqsxJobService.save(job);
        return Result.ok(job);
    }

    /**
     * 创建流程
     * @param lcmbCode 流程编码code
     * @param pid 业务id
     * @param dbrId 待办人id
     * @param nowNode 当前节点对象
     * @param nowJob 当前流程对象
     * @param nextNodeId 下一环节id
     * @param currentUser 当前登陆人
     * @param dbrMap 待办人对象（dbrId,dbr）
     * @return
     * {
     *     result.SpcySqsxJob
     * }
     */
    public Result createJob(String lcmbCode, String pid, String dbrId, SysFlowNode nowNode, SpcySqsxJob nowJob, String nextNodeId, CurrentUserVo currentUser, Map dbrMap){

        String dbr = "";
        if (dbrMap == null){
            dbrMap = this.verifryNextDbr(lcmbCode, pid, dbrId, nowNode, nowJob, nextNodeId, currentUser);
        }
        dbrId = dbrMap.get("dbrId").toString();
        dbr = dbrMap.get("dbr").toString();
        nowNode = (SysFlowNode) dbrMap.get("nowNode");

        String fnodeid = nowNode.getId();
        String fblfs = nowNode.getFblfs();
        String fjdmc = nowNode.getFjdmc();
        String lcmc = sysFlowNodeService.getCode(lcmbCode).getFlcmc();

        SpcySqsxJob job = new SpcySqsxJob();
        job.setId(GetUuIdUtils.ReplaceUuId());
        job.setFpid(pid);
        job.setFblfs(fblfs);
        job.setFhjmc(fjdmc);

        if(nowJob == null){
            job.setFsyhjid("");
        }else {
            job.setFsyhjid(nowJob.getId());
        }

        job.setFlcmc(lcmc); // 流程名称
        job.setFnodeid(fnodeid); // 结点id

        // 发送人
        if(currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }

        job.setFfssj(new Date());

        job.setFdbr(dbr);
        job.setFdbrid(dbrId);

        job.setFydbr(dbr);
        job.setFydbrid(dbrId);

        job.setFblzt(SpcyConstant.BLZT_DB);
        job.setFbllx(SpcyConstant.BLLX_DB);

        // 是否为审评查验流程
        boolean isSpcyFlow = SpcyFlowConstant.verifyIsSpcyFlow(lcmbCode);

        // 是否为审评查验流程 计算办理天数，是否超时状态
        if (isSpcyFlow){
            job.setFksyts(flowJobBlsxService.getSqsxSysx(pid));
            job.setFjzblsj(flowJobBlsxService.jsNodeJzrq(job.getFfssj(),job.getFksyts()));
        }

        spcySqsxJobService.save(job);
        return Result.ok(job);
    }

    /**
     * 判断下一环节是否存在待办人
     * @param lcmbCode 流程编码code
     * @param pid 业务id
     * @param dbrId 待办人id
     * @param nowNode 当前节点对象
     * @param nowJob 当前流程对象
     * @param nextNodeId 下一环节id
     * @param currentUser 当前登陆人
     * @return
     * {
     *     dbrId: 待办人id
     *     dbr: 待办人
     *     nowNode: 流程结点
     *     isEnd: true/false
     * }
     */
    public Map verifryNextDbr(String lcmbCode, String pid, String dbrId, SysFlowNode nowNode, SpcySqsxJob nowJob, String nextNodeId, CurrentUserVo currentUser){

        Map resultMap = new HashMap();

        if (nowNode == null) {
            if (StringUtils.isNotBlank(nextNodeId)) {
                nowNode = sysFlowNodeService.getById(nextNodeId);
            }

            // 如果nowJob 不为空
            if (StringUtils.isBlank(nextNodeId) && nowJob != null) {
                /**
                 * 根据当前结点id,获取下结点id
                 */
                String fnodeid1 = nowJob.getFnodeid();
                List<SysFlowNode> nextNodeList = sysFlowNodeService.getNextNode(fnodeid1);
                if (CollectionUtil.isEmpty(nextNodeList)) {
//                    throw new BusinessException("请配置对应" + lcmbCode + "对应流程的结点！");
                    resultMap.put("dbrId", "流程结束");
                    resultMap.put("dbr", "流程结束");
                    resultMap.put("nowNode", null);
                    resultMap.put("isEnd", true);
                    return resultMap;
                }

                if (nextNodeList.size() > 1) {
                    if (StringUtils.isBlank(nextNodeId)) {
                        throw new BusinessException("请选择要提交环节！");
                    } else {
                        nowNode = sysFlowNodeService.getById(nextNodeId);
                    }
                } else if (nextNodeList.size() == 1) {
                    nowNode = nextNodeList.get(0);
                }
            }
        }

        if (nowNode == null) {
            throw new BusinessException("请提供" + lcmbCode + "的流程结点！");
        }

        nextNodeId = nowNode.getId();

        String dbr = ""; // 待办人

        if (StringUtils.isBlank(dbrId)) {
            // 待办人和原待办人
            Integer fsfcjdpzhq = nowNode.getFsfcjdpzhq();
            // 是否从结点配置获取待办人: 0是/1否
            if (fsfcjdpzhq.equals(FlowNodeConstant.SFZD_YES)) {
                Map nodeDbrids = getNodeDbrids(lcmbCode, nextNodeId, nowNode, pid);
                dbrId = nodeDbrids.get("dbrId").toString();
                dbr = nodeDbrids.get("dbr").toString();
            } else {
                String fjdmc = nowNode.getFjdmc();
                Map dbrMap = this.getBtFlowNodeDbr(lcmbCode, pid, fjdmc);
                dbrId = dbrMap.get("dbrId").toString();
                dbr = dbrMap.get("dbr").toString();
            }
        }else {
            dbr = flowNodeDbrService.getDbrNameById(dbrId);
        }

        if (StringUtils.isBlank(dbrId)){
            throw new BusinessException("获取不到环节待办人！");
        }

        resultMap.put("dbrId", dbrId);
        resultMap.put("dbr", dbr);
        resultMap.put("nowNode", nowNode);
        resultMap.put("isEnd", false);
        return resultMap;
    }

    /**
     * 获取流程下环节待办人和办理页面
     * @param lcmbCode 流程模板编码
     * @param nowJob 当前流程任务
     * @param nextNodeId 下环节结点id
     * @return
     * {
     *     dbrId
     *     dbr:
     *     nextNode：下流程结点
     * }
     */
    public Map getNowJobInNextDbrAndHandlePageUrl(String lcmbCode, SpcySqsxJob nowJob,String nextNodeId){
        Map resultMap = new HashMap();
        SysFlowNode nextNode = null;
        String dbrId = "";

        if (nowJob == null){
            resultMap.put("dbrId", dbrId);
            resultMap.put("dbr", "");
            resultMap.put("nextNode", nextNode);

            return resultMap;
        }

        String pid = nowJob.getFpid();

        if (StringUtils.isBlank(nowJob.getFnodeid())){
            throw new BusinessException(nowJob.getFhjmc()+"当前流程任务不存在对应的节点参数！"+nowJob.getId());
        }
        String nowNodeId = nowJob.getFnodeid();

        SysFlowNode nowNode = sysFlowNodeService.getById(nowNodeId);
        if (nowNode == null){
            log.error("{}流程任务结点id: {}", nowJob.getFhjmc(), nowNodeId);
            throw new BusinessException("当前流程任务结点配置丢失！");
        }

        // 获取对应流程结点的办理页面路径
//        handlePageUrl = this.getNowJobHandlePageUrl(nowNode,nowNodeId);

        /**
         * 根据当前结点id,获取下结点id
         */
        if (StringUtils.isBlank(nextNodeId)) {

            List<SysFlowNode> nextNodeList = sysFlowNodeService.getNextNode(nowNodeId);
            if (nextNodeList.size() > 1) {
                if (StringUtils.isBlank(nextNodeId)) {
                    throw new BusinessException("请选择要提交环节！");
                } else {
                    nextNode = sysFlowNodeService.getById(nextNodeId);
                }
            } else if (nextNodeList.size() == 1) {
                nextNode = nextNodeList.get(0);
            }
        }else {
            nextNode = sysFlowNodeService.getById(nextNodeId);
        }

        // 不存在下环节流程结束
        if (nextNode == null){
            resultMap.put("dbrId", dbrId);
            resultMap.put("dbr", "");
            resultMap.put("nextNode", nextNode);

            return resultMap;
        }

        nextNodeId = nextNode.getId();

        String dbr = ""; // 待办人

        // 是否从该结点配置获取待办人
        Integer fsfcjdpzhq = nextNode.getFsfcjdpzhq();
        if (fsfcjdpzhq.equals(FlowNodeConstant.SFZD_YES)){
            Map nodeDbrids = getNodeDbrids(lcmbCode, nextNodeId, nextNode, pid);
            dbrId = nodeDbrids.get("dbrId").toString();
            dbr = nodeDbrids.get("dbr").toString();
        }else{
            String fjdmc = nextNode.getFjdmc();
            Map dbrMap = this.getBtFlowNodeDbr(lcmbCode, pid, fjdmc);
            dbrId = dbrMap.get("dbrId").toString();
            dbr = dbrMap.get("dbr").toString();
        }

        if (StringUtils.isBlank(dbrId)){
            throw new BusinessException("获取不到环节待办人！");
        }

        resultMap.put("dbrId", dbrId);
        resultMap.put("dbr", dbr);
        resultMap.put("nextNode", nextNode);
//        resultMap.put("handlePageUrl", handlePageUrl);

        return resultMap;
    }

    /**
     * 获取对应流程结点的办理页面路径
     * @param nowNode
     * @return
     */
    private SysFlowPage getNowJobHandlePageUrl(SysFlowNode nowNode,String nowNodeId){
        if (nowNode == null){
            nowNode = sysFlowNodeService.getById(nowNodeId);

            if (nowNode == null){
                log.error("当前流程任务结点id: {}", nowNodeId);
                throw new BusinessException("当前流程任务结点配置丢失！");
            }
        }



        if (StringUtils.isBlank(nowNode.getFymid())){
            throw new BusinessException("请配置相关的页面路径！");
        }

        SysFlowPage flowPage = sysFlowPageService.getById(nowNode.getFymid());
        /*
        // String handlePageUrl = "";
        if (flowPage == null){
            throw new BusinessException("页面路径丢失！请重新配置相关的页面路径！");
        }
        handlePageUrl = flowPage.getFymdz();*/

        return flowPage;
    }

    /**
     * 获取对应流程结点的办理页面路径
     * @param jobid 当前流程任务id
     */
    public SysFlowPage getHandlePageUrl(String jobid){
        SpcySqsxJob nowJob = spcySqsxJobService.getById(jobid);
        if (nowJob == null){
            throw new BusinessException("当前流程任务不存在！");
        }

        if (StringUtils.isBlank(nowJob.getFnodeid())){
            throw new BusinessException("当前流程任务结点参数为空！");
        }
        SysFlowNode nowNode = sysFlowNodeService.getById(nowJob.getFnodeid());
        if (nowNode == null){
            throw new BusinessException("当前流程任务结点配置为空！");
        }
        return this.getNowJobHandlePageUrl(nowNode, null);
    }

    /**
     * 退回
     * @param jobid 流程id
     * @param opinion 意见
     * @param syjobId 退回环节节点id
     * @param previousJob 退回环节流程任务
     * @return
     */
    public Result returnJob(String jobid, String syjobId, SpcySqsxJob previousJob, String opinion, CurrentUserVo currentUser){
        return this.returnJob(jobid, null,syjobId, previousJob, opinion, currentUser);
    }

    /**
     * 退回
     * @param jobid 流程id
     * @param opinion 意见
     * @param syjobId 退回环节节点id
     * @param previousJob 退回环节流程任务
     * @return
     */
    public Result returnJob(String jobid, SpcySqsxJob currentJob, String syjobId, SpcySqsxJob previousJob, String opinion, CurrentUserVo currentUser){

        // 当前环节
        if (currentJob == null) {
            currentJob = spcySqsxJobService.getById(jobid);

            if (currentJob == null){
                throw new BusinessException("退回失败！当前流程任务不存在！");
            }
        }

        if(StringUtils.isBlank(currentJob.getFdbrid())){
            return Result.error("当前任务未指定办理人！");
        }

        if (SpcyConstant.BLZT_YB.equals(currentJob.getFblzt())) {
            return Result.error("当前任务已提交！");
        }

        /** 环节不可以退回 */
        if (StringUtils.isNotBlank(currentJob.getFhjmc()) && currentJob.getFhjmc().equals(SpcyFlowConstant.HJMC_XCJC)){
            throw new BusinessException(SpcyFlowConstant.HJMC_XCJC + "无操作权限！当前所处环节无法退回！");
        }

        String pid = currentJob.getFpid();

        if (previousJob == null) {
            previousJob = spcySqsxJobService.getById(syjobId);
            if (previousJob == null) {
                throw new BusinessException("退回失败！选中的退回环节不存在！");
            }
        }

        String bllx = SpcyConstant.BLLX_TH + "[" + previousJob.getFhjmc()+ "]";
        /*Result result = this.doJob(currentJob, currentUser, opinion, bllx);
        if (!result.isSuccess()) {
            throw new BusinessException(result.getMessage());
        }*/

        String blrId = "";
        String blr = "";
        String blbm = "";
        if (true) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
            blbm = currentUser.getDeptName();

            if (!currentJob.getFdbrid().contains(blrId)) {
                return Result.error("当前登录用户无此任务的办理权限！");
            }
        }

        if (StringUtils.isBlank(opinion)){
            opinion = "不同意";
        }


        currentJob.setFblrid(blrId);
        currentJob.setFblr(blr);
        currentJob.setFblsj(new Date());
        currentJob.setFblyj(opinion);
        currentJob.setFblzt(SpcyConstant.BLZT_YB);
        currentJob.setFbllx(bllx);
        currentJob.setFblbm(blbm);

        // 审评查验流程 计算 办理天数、是否超时
        try {
            if (StringUtils.isNotBlank(currentJob.getFlcmc())
                    && (currentJob.getFlcmc().contains(SpcyFlowConstant.LCMC_LIKE_SPCYLC))) {

                currentJob.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(currentJob.getFksyts(),currentJob.getFpid(),currentJob.getFfssj(), currentJob.getFblsj(), currentJob.getFztkssj(),currentJob.getFztjssj())); // 使用天数
                currentJob.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(currentJob.getFsyts(), currentJob.getFcnts())); // 办理是否超时

            }else {

                currentJob.setFsyts(flowJobBlsxService.jssygzr(currentJob.getFfssj(), currentJob.getFblsj())); // 使用天数
                currentJob.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(currentJob.getFsyts(), currentJob.getFcnts())); // 办理是否超时
            }
        }catch (Exception e){
            log.error("流程办结时限计算错误: {}", e.getMessage());
        }

        boolean flag = spcySqsxJobService.updateById(currentJob);
        if (flag) {
            // 复制当前流程
            SpcySqsxJob newPreviousJob = copyNewJob(SpcyConstant.BLZT_TH, pid, null, null, previousJob, currentUser);

            return Result.ok(newPreviousJob);
        }else {
            return Result.error("操作失败！请重试！");
        }


    }

    /**
     * 创建指定环节
     *
     * @param opinion 办理意见
     * @param isVerifyAuth 验证权限
     * @param blr 办理人
     * @param dbrid 待办人id
     * @param dbr 待办人
     * @param zdhjid 指定环节id
     * @param zdhjmc 指定环节名称
     */
    public Result createZdJob(String jobid, SpcySqsxJob currentJob,
                              String opinion, CurrentUserVo currentUser,
                              boolean isVerifyAuth, String blr,
                              String dbrid, String dbr,
                              String zdhjid, String zdhjmc,
                              String ffsrid, String ffsrxm){
        // 当前环节
        if (currentJob == null) {
            currentJob = spcySqsxJobService.getById(jobid);

            if (currentJob == null){
                throw new BusinessException("退回失败！当前流程任务不存在！");
            }
        }
        String pid = currentJob.getFpid();

        Result result = this.doJob(jobid, currentJob, opinion, isVerifyAuth,"",blr,"");
        if (!result.isSuccess()) {

            log.error("创建指定环节失败：{}", result.getMessage());
            return Result.error(result.getMessage());
        }else {
            SpcySqsxJob newPreviousJob = copyNewJob(SpcyConstant.BLZT_DB, pid, zdhjid, zdhjmc, dbrid, dbr, currentJob, currentUser, ffsrid, ffsrxm);

            return Result.ok(newPreviousJob);
        }

    }

    /**
     * 内部转办流程
     * @param jobid 流程id
     * @param dbrid 办理人id
     * @param opinion 意见
     * @return
     */
    public Result transferFlowJob(String jobid, String dbrid, String opinion, CurrentUserVo currentUser){
        // 当前环节
        SpcySqsxJob currentJob = spcySqsxJobService.getById(jobid);
        if (currentJob == null){
            throw new BusinessException("退回失败！当前流程任务不存在！");
        }
        String pid = currentJob.getFpid();

        // 待办人
        String dbr = flowNodeDbrService.getDbrNameById(dbrid);

        String bllx = SpcyConstant.BLLX_ZB;
        Result result = this.doJob(currentJob, currentUser, opinion, bllx);
        if (!result.isSuccess()) {
            throw new BusinessException(result.getMessage());
        }

        // 复制当前流程
        SpcySqsxJob newPreviousJob = copyNewJob(SpcyConstant.BLZT_DB, pid, dbrid, dbr, currentJob, currentUser);

        return Result.ok(newPreviousJob);
    }

    /**
     *  复制新的流程
     * @param bllx 办理类型
     * @param pid 业务id
     * @param dbrid 待办人id
     * @param dbr 待办人
     * @param currentJob 当前流程任务
     * @param currentUser 当前用户
     * */
    private SpcySqsxJob copyNewJob(String bllx, String pid, String dbrid, String dbr, SpcySqsxJob currentJob, CurrentUserVo currentUser){
        return copyNewJob(bllx, pid, null, null, dbrid, dbr, currentJob, currentUser, null, null);
    }

    /**
     *  复制新的流程
     * @param bllx 办理类型
     * @param pid 业务id
     * @param zdhjid 指定环节id
     * @param zdhjmc 环节名称
     * @param dbrid 待办人id
     * @param dbr 待办人
     * @param currentJob 当前流程任务
     * @param currentUser 当前用户
     * @param ffsrid 发送人id
     * @param ffsrxm 发送人姓名
     * */
    public SpcySqsxJob copyNewJob(String bllx, String pid, String zdhjid, String zdhjmc, String dbrid, String dbr, SpcySqsxJob currentJob, CurrentUserVo currentUser, String ffsrid, String ffsrxm){
        return this.copyNewJob(bllx, pid, zdhjid, zdhjmc, dbrid, dbr, currentJob, currentUser, ffsrid, ffsrxm, "");
    }

    public SpcySqsxJob copyNewJob(String bllx, String pid, String zdhjid, String zdhjmc, String dbrid, String dbr, SpcySqsxJob currentJob, CurrentUserVo currentUser, String ffsrid, String ffsrxm, String blyj){
        SpcySqsxJob newPreviousJob = new SpcySqsxJob();

        try {
            if (currentJob != null) {
                BeanUtil.copyProperties(currentJob, newPreviousJob);
            }
        }catch (Exception e){
            log.error("复制新的流程-COPY-失败：{}", e.getMessage());
        }

        newPreviousJob.setId(GetUuIdUtils.NotReplaceUuId());
        newPreviousJob.setFpid(pid);

        if (StringUtils.isNotBlank(dbrid)){
            newPreviousJob.setFdbrid(dbrid);
//            String dbr = flowNodeDbrService.getDbrNameById(dbrid);
            newPreviousJob.setFdbr(dbr);

            newPreviousJob.setFydbr(dbr);
            newPreviousJob.setFydbrid(dbrid);
        }

        newPreviousJob.setFbllx(SpcyConstant.BLLX_DB);
        newPreviousJob.setFblzt(bllx);

        // 发送人
        if(currentUser != null) {
            newPreviousJob.setFfsrid(currentUser.getId());
            newPreviousJob.setFfsrmc(currentUser.getName());
        }

        if (StringUtils.isNotBlank(ffsrid)){
            newPreviousJob.setFfsrid(ffsrid);
        }
        if (StringUtils.isNotBlank(ffsrxm)){
            newPreviousJob.setFfsrmc(ffsrxm);
        }
        newPreviousJob.setFfssj(new Date());

        if (StringUtils.isNotBlank(blyj)) {
            newPreviousJob.setFblyj(blyj);
        }else {
            newPreviousJob.setFblyj("");
        }

        newPreviousJob.setFblrid("");
        newPreviousJob.setFblr("");
        newPreviousJob.setFblsj(null);

        newPreviousJob.setFblbm("");
        newPreviousJob.setFsyts("0");
        newPreviousJob.setFsfcs("");

        if (StringUtils.isNotBlank(zdhjid)){
            newPreviousJob.setFnodeid(zdhjid);
        }

        if (StringUtils.isNotBlank(zdhjmc)){
            newPreviousJob.setFhjmc(zdhjmc);
        }

        // 是否为审评查验流程 计算办理天数，是否超时状态
        try {
            if (StringUtils.isNotBlank(newPreviousJob.getFlcmc()) && newPreviousJob.getFlcmc().contains(SpcyFlowConstant.LCMC_LIKE_SPCYLC)) {
                newPreviousJob.setFksyts(flowJobBlsxService.getSqsxSysx(pid));
                newPreviousJob.setFjzblsj(flowJobBlsxService.jsNodeJzrq(newPreviousJob.getFfssj(), newPreviousJob.getFksyts()));
            }
        }catch (Exception e){
            log.error("计算时限错误：{}", e.getMessage());
        }

        newPreviousJob.setFztsyts("0");
        newPreviousJob.setFztkssj(null);
        newPreviousJob.setFztjssj(null);
        newPreviousJob.setFtszt("");

        newPreviousJob.setFlcsfkb(SpcyFlowConstant.JOB_LCSFKB_KB);
        newPreviousJob.setFbz("");
        spcySqsxJobService.save(newPreviousJob);

        return newPreviousJob;
    }

    public SpcySqsxJob copyZdyNewJob(String bllx, String pid, String zdhjid, String zdhjmc, String dbrid, String dbr, SpcySqsxJob currentJob, CurrentUserVo currentUser, String ffsrid, String ffsrxm){
        SpcySqsxJob newPreviousJob = new SpcySqsxJob();
        BeanUtil.copyProperties(currentJob, newPreviousJob);
        newPreviousJob.setId(GetUuIdUtils.NotReplaceUuId());
        newPreviousJob.setFpid(pid);

        if (StringUtils.isNotBlank(dbrid)){
            newPreviousJob.setFdbrid(dbrid);
            newPreviousJob.setFdbr(dbr);

            newPreviousJob.setFydbr(dbr);
            newPreviousJob.setFydbrid(dbrid);
        }

        newPreviousJob.setFbllx(SpcyConstant.BLLX_DB);
        newPreviousJob.setFblzt(bllx);

        // 发送人
        if(currentUser != null) {
            newPreviousJob.setFfsrid(currentUser.getId());
            newPreviousJob.setFfsrmc(currentUser.getName());
        }

        if (StringUtils.isNotBlank(ffsrid)){
            newPreviousJob.setFfsrid(ffsrid);
        }
        if (StringUtils.isNotBlank(ffsrxm)){
            newPreviousJob.setFfsrmc(ffsrxm);
        }
        newPreviousJob.setFfssj(new Date());

        newPreviousJob.setFblyj("");

        newPreviousJob.setFblrid("");
        newPreviousJob.setFblr("");
        newPreviousJob.setFblsj(null);

        newPreviousJob.setFblbm("");
        newPreviousJob.setFsyts("0");
        newPreviousJob.setFsfcs("");

        if (StringUtils.isNotBlank(zdhjid)){
            newPreviousJob.setFnodeid(zdhjid);
        }

        if (StringUtils.isNotBlank(zdhjmc)){
            newPreviousJob.setFhjmc(zdhjmc);
        }

        newPreviousJob.setFztsyts("0");
        newPreviousJob.setFztkssj(null);
        newPreviousJob.setFztjssj(null);
        newPreviousJob.setFtszt("");

        newPreviousJob.setFlcsfkb(SpcyFlowConstant.JOB_LCSFKB_KB);
        newPreviousJob.setFbz("");
        spcySqsxJobService.save(newPreviousJob);

        return newPreviousJob;
    }

    public SpcySqsxJob initNewJob(String pid, String dbrid, String dbr, String zdhjid, String zdhjmc, String flcmc, CurrentUserVo currentUser, String ffsrid, String ffsrxm){
        SpcySqsxJob newPreviousJob = new SpcySqsxJob();
        newPreviousJob.setId(GetUuIdUtils.NotReplaceUuId());
        newPreviousJob.setFpid(pid);

        if (StringUtils.isNotBlank(dbrid)){
            newPreviousJob.setFdbrid(dbrid);
            newPreviousJob.setFdbr(dbr);

            newPreviousJob.setFydbr(dbr);
            newPreviousJob.setFydbrid(dbrid);
        }

        newPreviousJob.setFbllx(SpcyConstant.BLLX_DB);
        newPreviousJob.setFblzt(SpcyConstant.BLLX_DB);

        // 发送人
        if(currentUser != null) {
            newPreviousJob.setFfsrid(currentUser.getId());
            newPreviousJob.setFfsrmc(currentUser.getName());
        }

        if (StringUtils.isNotBlank(ffsrid)){
            newPreviousJob.setFfsrid(ffsrid);
        }
        if (StringUtils.isNotBlank(ffsrxm)){
            newPreviousJob.setFfsrmc(ffsrxm);
        }
        newPreviousJob.setFfssj(new Date());

        newPreviousJob.setFblyj("");

        newPreviousJob.setFblrid("");
        newPreviousJob.setFblr("");
        newPreviousJob.setFblsj(null);

        newPreviousJob.setFblbm("");
        newPreviousJob.setFsyts("0");
        newPreviousJob.setFsfcs("");

        if (StringUtils.isNotBlank(zdhjid)){
            newPreviousJob.setFnodeid(zdhjid);
        }

        if (StringUtils.isNotBlank(zdhjmc)){
            newPreviousJob.setFhjmc(zdhjmc);
        }

        newPreviousJob.setFlcmc(flcmc);
        newPreviousJob.setFztsyts("0");
        newPreviousJob.setFztkssj(null);
        newPreviousJob.setFztjssj(null);
        newPreviousJob.setFtszt("");
        newPreviousJob.setFlcsfkb(SpcyFlowConstant.JOB_LCSFKB_KB);
        newPreviousJob.setFbz("");

        return newPreviousJob;
    }

    /**
     *  复制已办的流程
     * @param pid 业务id
     * @param zdhjid 指定环节id
     * @param zdhjmc 环节名称
     * @param dbrid 待办人id
     * @param dbr 待办人
     * @param currentJob 当前流程任务
     * @param currentUser 当前用户
     * @param ffsrid 发送人id
     * @param ffsrxm 发送人姓名
     * @param opinion 办理意见
     * */
    public SpcySqsxJob copyYbJob(String pid, String zdhjid, String zdhjmc,String dbrid, String dbr, SpcySqsxJob currentJob, CurrentUserVo currentUser, String ffsrid, String ffsrxm, String opinion){
       return this.copyYbJob(pid, zdhjid, zdhjmc, dbrid, dbr, currentJob, currentUser, ffsrid, ffsrxm, opinion, SpcyConstant.BLZT_YB);
    }
    public SpcySqsxJob copyYbJob(String pid, String zdhjid, String zdhjmc,String dbrid, String dbr, SpcySqsxJob currentJob, CurrentUserVo currentUser, String ffsrid, String ffsrxm, String opinion, String fblzt){
        SpcySqsxJob newPreviousJob = new SpcySqsxJob();
        if (currentJob != null) {
            BeanUtil.copyProperties(currentJob, newPreviousJob);
        }
        newPreviousJob.setId(GetUuIdUtils.NotReplaceUuId());
        newPreviousJob.setFpid(pid);

        if (StringUtils.isNotBlank(dbrid)){
            newPreviousJob.setFdbrid(dbrid);
            newPreviousJob.setFdbr(dbr);

            newPreviousJob.setFydbr(dbr);
            newPreviousJob.setFydbrid(dbrid);
        }

        newPreviousJob.setFbllx(SpcyConstant.BLLX_BL);
        newPreviousJob.setFblzt(fblzt);

        // 发送人
        if(currentUser != null) {
            newPreviousJob.setFfsrid(currentUser.getId());
            newPreviousJob.setFfsrmc(currentUser.getName());
        }

        if (StringUtils.isNotBlank(ffsrid)){
            newPreviousJob.setFfsrid(ffsrid);
        }
        if (StringUtils.isNotBlank(ffsrxm)){
            newPreviousJob.setFfsrmc(ffsrxm);
        }
        newPreviousJob.setFfssj(new Date());

        newPreviousJob.setFblyj(opinion);
        newPreviousJob.setFblrid(dbrid);
        newPreviousJob.setFblr(dbr);
        newPreviousJob.setFblsj(new Date());

        newPreviousJob.setFblbm("");
        newPreviousJob.setFsyts("0");
        newPreviousJob.setFsfcs("");

        if (StringUtils.isNotBlank(zdhjid)){
            newPreviousJob.setFnodeid(zdhjid);
        }

        if (StringUtils.isNotBlank(zdhjmc)){
            newPreviousJob.setFhjmc(zdhjmc);
        }

        newPreviousJob.setFztsyts("0");
        newPreviousJob.setFztkssj(null);
        newPreviousJob.setFztjssj(null);
        newPreviousJob.setFtszt("");

        newPreviousJob.setFlcsfkb(SpcyFlowConstant.JOB_LCSFKB_KB);
        newPreviousJob.setFbz("");
        spcySqsxJobService.save(newPreviousJob);

        return newPreviousJob;
    }

    /** 初始化构建数据结构 */
    public SpcySqsxJob copyGenJob(String pid, String zdhjid, String zdhjmc,
                                  String dbrid, String dbr, SpcySqsxJob currentJob,
                                  CurrentUserVo currentUser, String ffsrid, String ffsrxm,
                                  String opinion, String fblzt, String flcmc){
        SpcySqsxJob newPreviousJob = new SpcySqsxJob();

        if (currentJob != null) {
            BeanUtil.copyProperties(currentJob, newPreviousJob);
        }

        newPreviousJob.setId(GetUuIdUtils.NotReplaceUuId());
        newPreviousJob.setFpid(pid);

        if (StringUtils.isNotBlank(dbrid)){
            newPreviousJob.setFdbrid(dbrid);
            newPreviousJob.setFdbr(dbr);

            newPreviousJob.setFydbr(dbr);
            newPreviousJob.setFydbrid(dbrid);
        }

        newPreviousJob.setFbllx(SpcyConstant.BLLX_BL);
        newPreviousJob.setFblzt(fblzt);

        // 发送人
        if(currentUser != null) {
            newPreviousJob.setFfsrid(currentUser.getId());
            newPreviousJob.setFfsrmc(currentUser.getName());
        }

        if (StringUtils.isNotBlank(ffsrid)){
            newPreviousJob.setFfsrid(ffsrid);
        }
        if (StringUtils.isNotBlank(ffsrxm)){
            newPreviousJob.setFfsrmc(ffsrxm);
        }
        newPreviousJob.setFfssj(new Date());

        newPreviousJob.setFblyj(opinion);
        newPreviousJob.setFblrid(dbrid);
        newPreviousJob.setFblr(dbr);
        newPreviousJob.setFblsj(new Date());

        newPreviousJob.setFblbm("");
        newPreviousJob.setFsyts("0");
        newPreviousJob.setFsfcs("");

        if (StringUtils.isNotBlank(zdhjid)){
            newPreviousJob.setFnodeid(zdhjid);
        }

        if (StringUtils.isNotBlank(zdhjmc)){
            newPreviousJob.setFhjmc(zdhjmc);
        }

        newPreviousJob.setFztsyts("0");
        newPreviousJob.setFztkssj(null);
        newPreviousJob.setFztjssj(null);
        newPreviousJob.setFtszt("");
        if (StringUtils.isNotBlank(flcmc)) {
            newPreviousJob.setFlcmc(flcmc);
        }

        newPreviousJob.setFlcsfkb(SpcyFlowConstant.JOB_LCSFKB_KB);
        newPreviousJob.setFbz("");
        newPreviousJob.setCreateTime(new Date());

        return newPreviousJob;
    }

    /**
     * 办结环节任务
     * @param jobid 流程任务id
     * @Description 办结当前环节
     */
    public Result doJob(String jobid, String opinion){
        return doJob(jobid,null,opinion,true,null,null,null);
    }

    /**
     * 办结环节任务
     * @param job 流程任务
     * @Description 办结当前环节
     */
    public Result doJob(SpcySqsxJob job, String opinion){
        return doJob(null,job,opinion,true,null,null,null);
    }

    /**
     * 办结环节任务
     * @param job 流程任务
     * @Description 办结当前环节
     * @param bllx 办理类型
     */
    public Result doJob(SpcySqsxJob job, CurrentUserVo currentUser, String opinion, String bllx){
        return doJob(null,job,opinion,true,null,null,bllx);
    }

    /**
     * 办结环节任务
     * @param jobid 流程任务id
     * @param job 流程任务
     * @Description 办结当前环节
     * @param isVerifyAuth 是否验证权限(true：验证)
     * @param blrId 办理人id
     * @param blr 办理人
     * @param bllx 办理类型 （可空）
     * @return
     * {
     *     result.SpcySqsxJob
     * }
     */
    public Result doJob(String jobid, SpcySqsxJob job, String opinion, boolean isVerifyAuth,String blrId,String blr,String bllx) {

        if (job == null) {
            job = spcySqsxJobService.getById(jobid);
        }

        String blbm = "";
        if (job == null) {
            return Result.error("当前流程任务不存在！");
        }

        if(StringUtils.isBlank(job.getFdbrid())){
            return Result.error("当前任务未指定办理人");
        }

        if (SpcyConstant.BLZT_YB.equals(job.getFblzt())) {
            return Result.error("当前任务已提交！");
        }

        if (isVerifyAuth) {
            CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
            if (currentUser == null) {
                throw new BusinessException("登录已失效！请重新登录！");
            }

            blrId = currentUser.getId();
            blr = currentUser.getName();
            blbm = currentUser.getDeptName();

            if (!job.getFdbrid().contains(blrId)) {
                return Result.error("当前登录用户无此任务的办理权限");
            }
        }
        if (StringUtils.isBlank(opinion)){
            opinion = "同意";
        }

        // 办理方式  、多人竞争办理
        String blfs = job.getFblfs();
        if (StringUtils.isBlank(blfs) || blfs.equals(SpcyConstant.BLFS_DRJJ)) {
            job.setFblrid(blrId);
            job.setFblr(blr);
            job.setFblsj(new Date());
            job.setFblyj(opinion);
            job.setFblzt(SpcyConstant.BLZT_YB);

            if (StringUtils.isBlank(bllx)) {
                job.setFbllx(SpcyConstant.BLLX_BL);
            }else {
                job.setFbllx(bllx);
            }

            job.setFblbm(blbm);

            // 审评查验流程 计算 办理天数、是否超时
            try {
                if (StringUtils.isNotBlank(job.getFlcmc()) && (job.getFlcmc().contains(SpcyFlowConstant.LCMC_LIKE_SPCYLC))) {

                    job.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(job.getFksyts(),job.getFpid(),job.getFfssj(), job.getFblsj(), job.getFztkssj(),job.getFztjssj())); // 使用天数
                    job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时

                }else {

                    job.setFsyts(flowJobBlsxService.jssygzr(job.getFfssj(), job.getFblsj())); // 使用天数
                    job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时
                }
            }catch (Exception e){
                log.error("流程办结时限计算错误: {}", e.getMessage());
            }

            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        } else if (blfs.equals(SpcyConstant.BLFS_DRXX) || blfs.equals(SpcyConstant.BLFS_DRBX)) {

            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId = "";
            String nextBlr = "";
            if (blfs.equals(SpcyConstant.BLFS_DRXX)) {
                String ydbrIds[] = job.getFydbrid().split(",|，");
                String ydbrs[] = job.getFydbr().split(",|，");
                for (int i = 0; i < ydbrIds.length; i++) {
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (dbrId.equals(blrId)) {
                        if (i + 1 < ydbrIds.length) {
                            nextBlrId = ydbrIds[i + 1];
                            nextBlr = ydbrs[i + 1];
                            break;
                        }
                    }
                }
            } else {
                String dbrIds[] = job.getFdbrid().split(",|，");
                String dbrs[] = job.getFdbr().split(",|，");
                for (int i = 0; i < dbrIds.length; i++) {
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if (!dbrId.equals(blrId)) {
                        nextBlrId = nextBlrId + (StringUtils.isBlank(nextBlrId) ? "" : ",") + dbrId;
                        nextBlr = nextBlr + (StringUtils.isBlank(nextBlr) ? "" : ",") + dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            /*job.setFblr(blr);
            job.setFblsj(new Date());
            String blyj = (job.getFblyj() == null ? "" : job.getFblyj()) + (StringUtils.isBlank(job.getFblyj()) ? "" : "@@") + DateConversionUtils.DateToString(new Date()) + "|" + blr + "|" + opinion;
            job.setFblyj(blyj);*/

            if (StringUtils.isBlank(nextBlrId)) {
                job.setFblzt(SpcyConstant.BLZT_YB);
                if (StringUtils.isBlank(bllx)) {
                    job.setFbllx(SpcyConstant.BLLX_BL);
                }else {
                    job.setFbllx(bllx);
                }
                job.setFblrid(blrId);
                job.setFblbm(blbm);
                job.setFblr(blr);

                job.setFblsj(new Date());
                job.setFblyj(opinion);

                try{
                    // 审评查验流程 计算 办理天数、是否超时
                    if (StringUtils.isNotBlank(job.getFlcmc()) && (job.getFlcmc().contains(SpcyFlowConstant.LCMC_LIKE_SPCYLC))) {

                        job.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(job.getFksyts(),job.getFpid(),job.getFfssj(), job.getFblsj(), job.getFztkssj(),job.getFztjssj())); // 使用天数
                        job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时

                    }else {

                        job.setFsyts(flowJobBlsxService.jssygzr(job.getFfssj(), job.getFblsj())); // 使用天数
                        job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFsyts(), job.getFcnts())); // 办理是否超时
                    }
                }catch (Exception e){
                    log.error("流程办结时限计算错误: {}", e.getMessage());
                }

            } else {
                job.setFblzt(SpcyConstant.BLZT_DB);
                job.setFdbrid(nextBlrId);
                job.setFdbr(nextBlr);

                SpcySqsxJob nowJob = new SpcySqsxJob();
                BeanUtil.copyProperties(job, nowJob);
                nowJob.setId(GetUuIdUtils.ReplaceUuId());
//                nowJob.setFfssj(new Date());

                nowJob.setFdbrid(job.getFydbrid());
                nowJob.setFdbr(job.getFydbr());

                nowJob.setFblsj(new Date());
                nowJob.setFblbm(blbm);
                nowJob.setFblrid(blrId);
                nowJob.setFblr(blr);
                nowJob.setFblyj(opinion);

                nowJob.setFblzt(SpcyConstant.BLZT_YB);
                if (StringUtils.isBlank(bllx)) {
                    nowJob.setFbllx(SpcyConstant.BLLX_BL);
                }else {
                    nowJob.setFbllx(bllx);
                }
                try{
                    // 审评查验流程 计算 办理天数、是否超时
                    if (StringUtils.isNotBlank(nowJob.getFlcmc()) && (nowJob.getFlcmc().contains(SpcyFlowConstant.LCMC_LIKE_SPCYLC))) {

                        nowJob.setFsyts(flowJobBlsxService.jsTwoDateBetweenDays(nowJob.getFksyts(),nowJob.getFpid(),nowJob.getFfssj(), nowJob.getFblsj(), nowJob.getFztkssj(), nowJob.getFztjssj())); // 使用天数
                        nowJob.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(nowJob.getFsyts(), nowJob.getFcnts())); // 办理是否超时

                    }else {

                        nowJob.setFsyts(flowJobBlsxService.jssygzr(nowJob.getFfssj(), nowJob.getFblsj())); // 使用天数
                        nowJob.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(nowJob.getFsyts(), nowJob.getFcnts())); // 办理是否超时
                    }
                }catch (Exception e){
                    log.error("流程办结时限计算错误: {}", e.getMessage());
                }
                spcySqsxJobService.save(nowJob);

            }

            spcySqsxJobService.updateById(job);


            return Result.ok(job);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /**
     * 办结流程任务
     */
    public Result bjCommonJob(String jobid, SpcySqsxJob updateJob, String opinion){
        if (updateJob == null){
            updateJob = spcySqsxJobService.getById(jobid);
        }

        updateJob.setFblzt(SpcyConstant.BLZT_YB);
        updateJob.setFbllx(SpcyConstant.BLLX_BL);
        updateJob.setFblsj(new Date());
        updateJob.setFblrid(GetCurrentUserUtils.getCurrentUserId());
        updateJob.setFblbm(GetCurrentUserUtils.getCurrentUserOrgName());
        updateJob.setFblr(GetCurrentUserUtils.getCurrentUserName());

        if (StringUtils.isBlank(updateJob.getFblrid())){
            updateJob.setFblrid(StringPatternUtils.cutFirstComma(updateJob.getFdbrid()));
        }

        if (StringUtils.isBlank(updateJob.getFblr())){
            updateJob.setFblr(StringPatternUtils.cutFirstComma(updateJob.getFdbr()));
        }

        updateJob.setFblyj(opinion);

        try{
            updateJob.setFsyts(flowJobBlsxService.jssygzr(updateJob.getFfssj(), updateJob.getFblsj())); // 使用天数
            updateJob.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(updateJob.getFsyts(), updateJob.getFcnts())); // 办理是否超时
        }catch (Exception e){
            log.error("办结流程任务-计算事项错误：{}", e.getMessage());
        }

        boolean flag = spcySqsxJobService.updateById(updateJob);
        if (!flag){
            return Result.error("更新失败！");
        }

        return Result.ok();
    }

    /**
     *  提交任务
     * @param lcmbCode 流程模板编码
     * @param pid 主业务id
     * @param jobId 流程id
     * @param opinion 意见
     * @param nextNodeId 下一节点id
     * @param nextNodeDbrIds 下一节点待办人
     * @return
     */
    public Result passJob(String lcmbCode, String pid, String jobId, String opinion, String nextNodeId, String nextNodeDbrIds) {
        return passJob(lcmbCode,pid,jobId,opinion,nextNodeId,nextNodeDbrIds,true);
    }

    /**
     *  提交任务
     * @param lcmbCode 流程模板编码
     * @param pid 主业务id
     * @param jobId 流程id
     * @param opinion 意见
     * @param nextNodeId 下一节点id
     * @param nextNodeDbrIds 下一节点待办人
     * @param isOverCurrentJob 是否办结 创建
     * @return
     */
    public Result passJob(String lcmbCode, String pid, String jobId, String opinion, String nextNodeId, String nextNodeDbrIds, boolean isOverCurrentJob){

        // 获得当前待办任务，并做校验
        SpcySqsxJob job= spcySqsxJobService.getById(jobId);
        if (job == null){
            return Result.error("查询不到id为【"+jobId+"】的待办任务!");
        }

        //获取办理人，并做办理人的校验，如果当前登录人不是待办人之一，拒绝办理
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            return Result.error("请先登录");
        }

        // 判断是否存在待办人
        Map dbrMap = this.verifryNextDbr(lcmbCode,pid,nextNodeDbrIds,null,job,nextNodeId,currentUser);
        boolean isFlowEnd = (boolean)dbrMap.get("isEnd");

        if(isOverCurrentJob){
            //办理掉当前环节
            Result result = doJob(jobId,opinion);

            //生成下一环节的待办
            if(result.isSuccess()){
                if (!isFlowEnd) {
                    job = (SpcySqsxJob) result.getResult();
                    if (job.getFblzt().equals(SpcyConstant.BLZT_YB)) {

//                        if (StringUtils.isBlank(job.getFlcbt())) {
                            //创建下一环节任务
                            Result result1 = createJob(lcmbCode, pid, nextNodeDbrIds, null, job, nextNodeId, currentUser, dbrMap);
                            if (!result1.isSuccess()) {
                                return Result.error(result1.getMessage());
                            } else {
                                // 3-16 返回新增的流程任务
                                return Result.ok(result1.getResult());
                            }
                        /*}else {
                            //创建下一环节任务
                            Result result1 = createJob(lcmbCode, pid, nextNodeDbrIds, null, job, nextNodeId, currentUser, dbrMap, "", job.getFbz(), "");
                            if (!result1.isSuccess()) {
                                return Result.error(result1.getMessage());
                            } else {
                                // 3-16 返回新增的流程任务
                                return Result.ok(result1.getResult());
                            }
                        }*/
                    }
                    // 3-16 返回当前流程任务
                    return Result.ok(job);
                }else {
                    return Result.ok(job);
                }
            }else{
                return Result.error(result.getMessage());
            }
        }else{
            if (isFlowEnd) {
                //创建下一环节任务
                Result result1 = createJob(lcmbCode, pid, nextNodeDbrIds, null, job, nextNodeId, currentUser, dbrMap);
                if (!result1.isSuccess()) {
                    return Result.error(result1.getMessage());
                } else {
                    // 3-16 返回新增的流程任务
                    return Result.ok(result1.getResult());
                }
            }

            return Result.ok(job);
        }
    }

    /**
     * 获取当前结点待办人
     * @param nowNodeid 当前节点id
     * @return
     */
    public Map getNodeDbrids(String lcmbCode, String nowNodeid, String pid){
         return getNodeDbrids(lcmbCode, nowNodeid, null, pid);
    }

    public Map getNodeDbrids(String lcmbCode, String nowNodeid, SysFlowNode sysFlowNode, String pid){

        if (sysFlowNode == null) {
            sysFlowNode = sysFlowNodeService.getById(nowNodeid);
        }

        Integer fsfcjdpzhq = sysFlowNode.getFsfcjdpzhq(); //是否从节点配置获取待办人
        String fblbmlx = sysFlowNode.getFblbmlx(); //办理部门类型
        String fblbmid = sysFlowNode.getFblbmid(); //办理部门id

        String fblgwid = sysFlowNode.getFblgwid(); //办理岗位id

        String fblrid = sysFlowNode.getFblrid(); //办理人id
        Integer fsfzdblr = sysFlowNode.getFsfzdblr(); //是否指定办理人
        Integer fsfzddlr= sysFlowNode.getFsfzddlr(); //是否指定登陆人为办理人

        Map map = new HashMap();

        //是否从节点配置获取待办人：0是 / 1否  为0则读取当前节点配置的环节办理人
        if (fsfcjdpzhq.equals(FlowNodeConstant.SFZD_YES)){

            //如果指定办理人 直接返回指定人
            if (fsfzdblr != null && fsfzdblr.equals(FlowNodeConstant.SFZD_YES)){
                if (StringUtils.isBlank(fblrid)){
                    throw new BusinessException("查询不到指定办理人");
                }
                String dbrName = flowNodeDbrService.getDbrNameById(fblrid);
                map.put("dbr",dbrName);
                map.put("dbrId",fblrid);
                return map;
            }

            //如果指定当前登陆人 则返回当前登录用户
            if (fsfzddlr != null && fsfzddlr.equals(FlowNodeConstant.SFZD_YES)){
                CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
                if (currentUser == null){
                    throw new BusinessException("当前登录已失效！请重新登录！");
                }
                String dbrid = currentUser.getId();
                String dbrname = currentUser.getName();
                map.put("dbr",dbrname);
                map.put("dbrId",dbrid);
                return map;
            }

            // 根据办理部门id+岗位id-获取对应的人员
            Map dbrByBmGw = getDbrByBmGw(fblbmid, fblgwid);

            //如果办理部门类型为 指定 则待办人 进入 根据部门和岗位判断
            if (fblbmlx.equals(FlowNodeConstant.BLJD_BLBM_ZD)){
                return dbrByBmGw;

                //在判断 办理部门类型为 不指定 则 待办人 根据 办理岗位id 来 判断
            }else if(fblbmlx.equals(FlowNodeConstant.BLJD_BLBM_BZD)){

                //否则根据办理部门id返回待办人
                return dbrByBmGw;
            }else if (fblbmlx.equals(FlowNodeConstant.BLJD_BLBM_DQBM)){

                return dbrByBmGw;
            }
        }else {

            String fjdmc = sysFlowNode.getFjdmc();
            this.getBtFlowNodeDbr(lcmbCode, pid, fjdmc);

            return map;
        }
        return map;
    }

    /**
     * 不从流程配置中获取待办人-根据不同流程-获取不同流程对应结点的待办人
     * @param lcmbCode 流程编码
     * @param pid 业务id
     * @param fjdmc 结点名称
     * @return
     */
    private Map getBtFlowNodeDbr(String lcmbCode, String pid,String fjdmc){

        /*if (lcmbCode.equals(SpcyFlowConstant.YPZC_FLOW_CODE_ZWFW) || lcmbCode.equals(SpcyFlowConstant.YPZC_FLOW_CODE_RCJG)) {
            String deptName = SpcyConstant.YPZC_ORG_NAME;
            return spcyFlowService.getNodeDbr(pid, fjdmc, deptName);
        }*/

        if (lcmbCode.equals(SpcyFlowConstant.YPSC_FLOW_CODE_ZWFW) || lcmbCode.equals(SpcyFlowConstant.YPSC_FLOW_CODE_RCJG)) {
            String deptName = SpcyConstant.YPSC_ORG_NAME;
            return spcyFlowService.getNodeDbr(pid, fjdmc, deptName);
        }

        /*if (lcmbCode.equals(SpcyFlowConstant.YPLT_FLOW_CODE_ZWFW) || lcmbCode.equals(SpcyFlowConstant.YPLT_FLOW_CODE_RCJG)) {
            String deptName = SpcyConstant.YPLT_ORG_NAME;
            return spcyFlowService.getNodeDbr(pid, fjdmc, deptName);
        }

        if (lcmbCode.equals(SpcyFlowConstant.YLQX_FLOW_CODE_ZWFW) || lcmbCode.equals(SpcyFlowConstant.YLQX_FLOW_CODE_RCJG)) {
            String deptName = SpcyConstant.YLQX_ORG_NAME;
            return spcyFlowService.getNodeDbr(pid, fjdmc, deptName);
        }

        if (lcmbCode.equals(SpcyFlowConstant.HZP_FLOW_CODE_ZWFW) || lcmbCode.equals(SpcyFlowConstant.HZP_FLOW_CODE_RCJG)) {
            String deptName = SpcyConstant.HZP_ORG_NAME;
            return spcyFlowService.getNodeDbr(pid, fjdmc, deptName);
        }*/

        // 补齐补正
        if (lcmbCode.equals(SpcyFlowConstant.BQBZ_001002_FLOW_CODE)){
            return bqbzFlowService.getNodeDbr(pid, fjdmc);
        }

        // 退回政务
        if (lcmbCode.equals(SpcyFlowConstant.THZWFW_001002_FLOW_CODE)){
            return thzwYpscFlowService.getNodeDbr(pid, fjdmc);
        }

        // 预备考评
        if (lcmbCode.equals(SpcyFlowConstant.KP_YBJCY_FLOW_CODE)){
            return jcyYbkpFlowService.getNodeDbr(pid, fjdmc);
        }

        // 日常考评
        if (lcmbCode.equals(SpcyFlowConstant.KP_RCKH_FLOW_CODE)){
            return jcyRckpFlowService.getNodeDbr(pid, fjdmc);
        }

        // 年度考评
        if (lcmbCode.equals(SpcyFlowConstant.KP_NDKH_FLOW_CODE)){
            return jcyNdkpFlowService.getNodeDbr(pid, fjdmc);
        }

        // 日常考评互评
        if (lcmbCode.equals(SpcyFlowConstant.KP_RCKHHP_FLOW_CODE)){
            return jcyRckpHpFlowService.getNodeDbr(pid, fjdmc);
        }

        // 体系文件流程
        if (lcmbCode.equals(SpcyFlowConstant.ZLTXWJ_FLOW_CODE)){
            return txwjFlowService.getNodeDbr(pid, fjdmc);
        }

        // 审评数据修订
        if (lcmbCode.equals(SpcyFlowConstant.SPCY_SJXD_FLOW_CODE)){
            return spcySjxdFlowService.getNodeDbr(pid, fjdmc);
        }

        Map resultMap = new HashMap();
        resultMap.put("dbrId", "");
        resultMap.put("dbr", "");
        return resultMap;
    }

    /**
     * 获取对应流程申请人当前部门
     */
    private Map getBtFlowSqrNowDept(String pid){


        return null;
    }

    /**
     * 根据办理部门id 和 办理岗位id 判断返回待办人
     * @param fblbmid
     * @param fblgwid
     * @return
     */
    private Map getDbrByBmGw(String fblbmid,String fblgwid){
        Map map = new HashMap();
        String dbr="";
        String dbrid="";
        //null null  办理部门id和办理岗位id都为空 直接返回为空
        if (StringUtils.isBlank(fblbmid) && StringUtils.isBlank(fblgwid)){
            map.put("dbr",dbr);
            map.put("dbrId",dbrid);
            return map;
        }
        //null not  办理部门id为空 办理岗位id不为空  返回当前办理岗位的所有人
        if (StringUtils.isBlank(fblbmid) && StringUtils.isNotBlank(fblgwid)){
            Map dbrByGwid = flowNodeDbrService.getDbrByGwid(fblgwid);
            return dbrByGwid;
        }
        //not null 办理部门id不为空 办理岗位id为空  返回当前部门id的所有人
        if (StringUtils.isNotBlank(fblbmid) && StringUtils.isBlank(fblgwid)){
            Map dbrByBmid = flowNodeDbrService.getDbrByBmid(fblbmid);
            return dbrByBmid;
        }
        // not not 办理部门id 和办理岗位id 都不为空 则返回当前部门下 当前办理岗位的用户
        if (StringUtils.isNotBlank(fblbmid) && StringUtils.isNotBlank(fblgwid)){

            // 先判断办理岗位id 是不是分管领导
            List<SysJob> sysJobs = sysJobService.list(new LambdaQueryWrapper<SysJob>().eq(SysJob::getId, fblgwid));
            String jobName = sysJobs.get(0).getJobName();
            if (jobName.equals(FlowNodeConstant.ROLE_NAME_FGLD)){
                return flowNodeDbrService.getFgldByDeptId(fblbmid);
            }else {
                return flowNodeDbrService.getdbrByDeptName(fblbmid, fblgwid);
            }
        }

        map.put("dbr",dbr);
        map.put("dbrId",dbrid);
        return map;
    }



}
